package edu.westga.sketchit2009cs.gui;

import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFormattedTextField;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

/**
 * JoinPanel defines the framework of the GUI for joining a current
 * Sketchit2009cs game. Its content pane will be allow clients to insert their
 * name, host's port number and the host's IP address to join. This Panel also
 * defines their computer as the client for the game.
 * 
 * @author Steven Campbell, RJ Hill, Daniel Reeves, Fall 2009
 * 
 */
public class JoinPanel extends JPanel {

	private static final long serialVersionUID = 1L;
	private JPanel joinComponents;
	private JLabel playerNameLabel;
	public JFormattedTextField playerTextField;
	private JFormattedTextField ipTextFieldOne;
	private JFormattedTextField ipTextFieldTwo;
	private JFormattedTextField ipTextFieldThree;
	private JFormattedTextField ipTextFieldFour;
	private JLabel periodLabel;
	public JFormattedTextField portTextField;
	private JPanel buttonPanel;
	private JLabel ipLabel;
	private JLabel portLabel;
	public final String JOIN_WELCOME_MESSAGE_STRING_VALUES = "Please insert the Required information to Join a game.";
	public final String PERIOD_STRING_VALUE = ".";
	public final String PLAYER_NAME_LABEL_STRING_VALUE = "Player Name";
	public final String IP_ADDRESS_LABEL_STRING_VALUE = "IP address";
	public final String PORT_NUMBER_LABEL_STRING_VALUE = "Port Number";
	public final String DEFAULT_PORT_NUMBER_STRING_VALUE = "5000";
	public final String OK_BUTTON_STRING_VALUE = "    OK    ";
	public final String CANCEL_BUTTON_STRING_VALUE = "Cancel";
	public final String CLEAR_BUTTON_STRING_VALUE = "Clear Form";
	public final String NULL_STRING_VALUE = "";
	public final String PLAYER_NAME_ERROR_STRING_VALUE = "Error. Incorrect Data in Player Name";
	public final String PLAYER_NAME_REQUIREMENTS_STRING_VALUE = "Your name can only be 3 - 20 characters.";
	public final String IP_ADDRESS_REQUIREMENTS_STRING_VALUE = "Each IP address textbox can must be a value between 0 and 255.";
	public final String IP_ADDRESS_ERROR_STRING_VALUE = "Error. Incorrect Data in IP address";
	public final String IP_ADDRESS_EXCEPTION_MESSAGE_STRING_VALUE = "The IP address can only have numbers in it and cannot be blank.";
	public final String PORT_NUMBER_REQUIREMENTS_STRING_VALUE = "The port can only be between 1024 and 65535.";
	public final String PORT_NUMBER_ERROR_STRING_VALUE = "Error. Incorrect Data in Port number.";
	public final String PORT_NUMBER_EXCEPTION_MESSAGE_STRING_VALUE = "The port can only have numbers in it, cannot be blank, and must be"
			+ " between 1024 and 65535.";
	public final String A = "";

	public JoinPanel() throws Exception {
		super();

		this.build();
	}

	// Creates the JoinPanel on the current GUI.
	public void build() throws Exception {
		joinComponents = new JPanel();
		this.setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
		this.setAlignmentX(Component.CENTER_ALIGNMENT);

		setUpUserInformation();
		this.setBackground(Color.LIGHT_GRAY);
	}

	// adds the welcome message to the Join panel
	private void addWelcomeMessage() throws Exception {

		JPanel welcomeMessagePanel = new JPanel();
		welcomeMessagePanel.setLayout(new BoxLayout(welcomeMessagePanel,
				BoxLayout.X_AXIS));
		welcomeMessagePanel.setAlignmentX(Component.CENTER_ALIGNMENT);
		JLabel welcomeMessageLabel = new JLabel(
				JOIN_WELCOME_MESSAGE_STRING_VALUES);
		welcomeMessagePanel.setBackground(Color.LIGHT_GRAY);
		welcomeMessagePanel.add(welcomeMessageLabel);

		this.joinComponents.add(welcomeMessagePanel);
	}

	// Sets up the Player Required information to join a game.
	private void setUpUserInformation() throws Exception {

		this.joinComponents.setLayout(new BoxLayout(this.joinComponents,
				BoxLayout.Y_AXIS));
		this.joinComponents.setAlignmentY(Component.CENTER_ALIGNMENT);
		this.joinComponents.setBackground(Color.LIGHT_GRAY);

		this.joinComponents.add(Box.createRigidArea(new Dimension(0, 75)));
		addWelcomeMessage();
		this.joinComponents.add(Box.createRigidArea(new Dimension(0, 25)));
		addPlayerName();
		this.joinComponents.add(Box.createRigidArea(new Dimension(0, 25)));
		addIpAddress();
		this.joinComponents.add(Box.createRigidArea(new Dimension(0, 25)));
		addPortNumber();
		this.joinComponents.add(Box.createRigidArea(new Dimension(0, 25)));
		setButtonDisplayPanel();
		this.joinComponents.add(Box.createRigidArea(new Dimension(0, 250)));

		this.add(this.joinComponents);

	}

	// Adds Player name components
	private void addPlayerName() throws Exception {
		JPanel addPlayerPanel = new JPanel();
		addPlayerPanel
				.setLayout(new BoxLayout(addPlayerPanel, BoxLayout.X_AXIS));
		addPlayerPanel.setAlignmentX(Component.CENTER_ALIGNMENT);
		this.playerNameLabel = new JLabel();
		addPlayerPanel.add(Box.createRigidArea(new Dimension(50, 0)));
		this.playerNameLabel.setText(PLAYER_NAME_LABEL_STRING_VALUE);
		this.playerNameLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
		addPlayerPanel.setBackground(Color.LIGHT_GRAY);
		this.playerTextField = new JFormattedTextField();
		this.playerTextField.setMaximumSize(new Dimension(250, 20));
		addPlayerPanel.add(this.playerNameLabel);
		addPlayerPanel.add(Box.createRigidArea(new Dimension(30, 0)));
		addPlayerPanel.add(this.playerTextField);
		addPlayerPanel.add(Box.createRigidArea(new Dimension(150, 0)));
		this.joinComponents.add(addPlayerPanel);

	}

	// Adds IP address components
	private void addIpAddress() throws Exception {
		JPanel addIpAddressPanel = new JPanel();
		addIpAddressPanel.setLayout(new BoxLayout(addIpAddressPanel,
				BoxLayout.X_AXIS));
		addIpAddressPanel.setAlignmentX(Component.CENTER_ALIGNMENT);
		this.ipLabel = new JLabel();
		addIpAddressPanel.add(Box.createRigidArea(new Dimension(20, 0)));
		this.periodLabel = new JLabel(PERIOD_STRING_VALUE);
		this.ipLabel.setText(IP_ADDRESS_LABEL_STRING_VALUE);
		this.ipTextFieldOne = new JFormattedTextField();
		this.ipTextFieldOne.setMaximumSize(new Dimension(50, 20));
		this.ipTextFieldTwo = new JFormattedTextField();
		this.ipTextFieldTwo.setMaximumSize(new Dimension(50, 20));
		this.ipTextFieldThree = new JFormattedTextField();
		this.ipTextFieldThree.setMaximumSize(new Dimension(50, 20));
		this.ipTextFieldFour = new JFormattedTextField();
		this.ipTextFieldFour.setMaximumSize(new Dimension(50, 20));
		this.ipLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
		addIpAddressPanel.setBackground(Color.LIGHT_GRAY);
		addIpAddressPanel.add(this.ipLabel);
		addIpAddressPanel.add(Box.createRigidArea(new Dimension(40, 0)));
		addIpAddressPanel.add(this.ipTextFieldOne);
		addIpAddressPanel.add(Box.createRigidArea(new Dimension(2, 5)));
		addIpAddressPanel.add(this.periodLabel);
		addIpAddressPanel.add(Box.createRigidArea(new Dimension(2, 5)));
		addIpAddressPanel.add(this.ipTextFieldTwo);
		this.periodLabel = new JLabel(PERIOD_STRING_VALUE);
		addIpAddressPanel.add(Box.createRigidArea(new Dimension(2, 5)));
		addIpAddressPanel.add(this.periodLabel);
		this.periodLabel = new JLabel(PERIOD_STRING_VALUE);
		addIpAddressPanel.add(Box.createRigidArea(new Dimension(2, 5)));
		addIpAddressPanel.add(this.ipTextFieldThree);
		addIpAddressPanel.add(this.periodLabel);
		addIpAddressPanel.add(Box.createRigidArea(new Dimension(2, 5)));
		addIpAddressPanel.add(this.ipTextFieldFour);
		addIpAddressPanel.add(Box.createRigidArea(new Dimension(150, 0)));
		this.joinComponents.add(addIpAddressPanel);

	}

	// Adds Port number components
	private void addPortNumber() throws Exception {
		JPanel addPortPanel = new JPanel();
		addPortPanel.setLayout(new BoxLayout(addPortPanel, BoxLayout.X_AXIS));
		addPortPanel.setAlignmentX(Component.CENTER_ALIGNMENT);
		this.portLabel = new JLabel();
		this.portLabel.setText(PORT_NUMBER_LABEL_STRING_VALUE);
		this.portLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
		addPortPanel.setBackground(Color.LIGHT_GRAY);
		this.portTextField = new JFormattedTextField();
		this.portTextField.setMaximumSize(new Dimension(75, 20));
		addPortPanel.add(this.portLabel);
		this.portTextField.setText(DEFAULT_PORT_NUMBER_STRING_VALUE);
		addPortPanel.add(Box.createRigidArea(new Dimension(30, 0)));
		addPortPanel.add(this.portTextField);
		addPortPanel.add(Box.createRigidArea(new Dimension(275, 0)));
		this.joinComponents.add(addPortPanel);

	}

	// Sets up the Ok and Cancel buttons
	private void setButtonDisplayPanel() throws Exception {
		this.buttonPanel = new JPanel();
		this.buttonPanel.setLayout(new BoxLayout(this.buttonPanel,
				BoxLayout.X_AXIS));
		this.buttonPanel.setAlignmentX(Component.CENTER_ALIGNMENT);
		this.buttonPanel.setBackground(Color.LIGHT_GRAY);
		JButton okButton = new JButton(OK_BUTTON_STRING_VALUE);
		okButton.addActionListener(new OkButtonListener());
		JButton cancelButton = new JButton(CANCEL_BUTTON_STRING_VALUE);
		cancelButton
				.addActionListener(new Sketchit2009csMainFrame.CancelButtonListener());
		JButton clearAllButton = new JButton(CLEAR_BUTTON_STRING_VALUE);
		clearAllButton.addActionListener(new ClearAllButtonListener());
		clearAllButton.setAlignmentX(RIGHT_ALIGNMENT);
		this.buttonPanel.add(Box.createRigidArea(new Dimension(100, 5)));
		this.buttonPanel.add(okButton);
		this.buttonPanel.add(Box.createRigidArea(new Dimension(50, 5)));
		this.buttonPanel.add(cancelButton);
		this.buttonPanel.add(Box.createRigidArea(new Dimension(50, 5)));
		this.buttonPanel.add(clearAllButton);
		this.buttonPanel.add(Box.createRigidArea(new Dimension(100, 5)));

		this.joinComponents.add(buttonPanel);
	}

	// Action listener that lets you cancel Join Game.
	private class ClearAllButtonListener implements ActionListener {

		/*
		 * Clears out the Text Field panels.
		 */
		@Override
		public void actionPerformed(ActionEvent e) {
			playerTextField.setText(NULL_STRING_VALUE);
			ipTextFieldOne.setText(NULL_STRING_VALUE);
			ipTextFieldTwo.setText(NULL_STRING_VALUE);
			ipTextFieldThree.setText(NULL_STRING_VALUE);
			ipTextFieldFour.setText(NULL_STRING_VALUE);
			portTextField.setText(NULL_STRING_VALUE);
		}
	}

	// Action listener that lets you Join a Game.
	private class OkButtonListener implements ActionListener {

		/*
		 * Loads the Game interface panel.
		 */
		@Override
		public void actionPerformed(ActionEvent e) {
			boolean correctInfo = checkPlayerInformation();

			if (correctInfo == true) {
				String fullIpAddress = ipTextFieldOne.getText()
						+ PERIOD_STRING_VALUE + ipTextFieldTwo.getText()
						+ PERIOD_STRING_VALUE + ipTextFieldThree.getText()
						+ PERIOD_STRING_VALUE + ipTextFieldFour.getText();
				Sketchit2009csMainFrame.hostAndJoinPortNumber = Integer
						.parseInt(portTextField.getText());
				Sketchit2009csMainFrame.playerName = playerTextField.getText();
				joinComponents.removeAll();
				joinComponents.add(new GameInterface(fullIpAddress));
				joinComponents.validate();
				joinComponents.repaint();

			}
		}

		// Method that checks to see if host information inserted is correct.
		private boolean checkPlayerInformation() {

			// Test the player's name
			if (playerTextField.getText().length() > 20
					|| playerTextField.getText().length() < 3) {
				JDialog errorDialog = new JDialog();
				JOptionPane.showMessageDialog(errorDialog,
						PLAYER_NAME_REQUIREMENTS_STRING_VALUE,
						PLAYER_NAME_ERROR_STRING_VALUE, 0);
				return false;
			}

			// Test the inserted IP address
			try {
				int parseTextFieldOne = Integer.parseInt(ipTextFieldOne
						.getText().trim());
				int parseTextFieldTwo = Integer.parseInt(ipTextFieldTwo
						.getText().trim());
				int parseTextFieldThree = Integer.parseInt(ipTextFieldThree
						.getText().trim());
				int parseTextFieldFour = Integer.parseInt(ipTextFieldFour
						.getText().trim());
				if (parseTextFieldOne < 0 || parseTextFieldOne > 255
						|| parseTextFieldTwo < 0 || parseTextFieldTwo > 255
						|| parseTextFieldThree < 0 || parseTextFieldThree > 255
						|| parseTextFieldFour < 0 || parseTextFieldFour > 255) {
					JDialog errorDialog = new JDialog();
					JOptionPane.showMessageDialog(errorDialog,
							IP_ADDRESS_REQUIREMENTS_STRING_VALUE,
							IP_ADDRESS_ERROR_STRING_VALUE, 0);
					return false;
				}
			} catch (NumberFormatException e) {
				JDialog errorDialog = new JDialog();
				JOptionPane.showMessageDialog(errorDialog,
						IP_ADDRESS_EXCEPTION_MESSAGE_STRING_VALUE,
						IP_ADDRESS_ERROR_STRING_VALUE, 0);
				return false;
			}

			// Test the port number of the user.
			try {
				int theParsed = Integer
						.parseInt(portTextField.getText().trim());
				if (theParsed < 1024 || theParsed > 65535) {
					JDialog errorDialog = new JDialog();
					JOptionPane.showMessageDialog(errorDialog,
							PORT_NUMBER_REQUIREMENTS_STRING_VALUE,
							PORT_NUMBER_ERROR_STRING_VALUE, 0);
					return false;
				}

			} catch (NumberFormatException e) {
				JDialog errorDialog = new JDialog();
				JOptionPane.showMessageDialog(errorDialog,
						PORT_NUMBER_EXCEPTION_MESSAGE_STRING_VALUE,
						PORT_NUMBER_ERROR_STRING_VALUE, 0);
				return false;
			}

			return true;
		}
	}
}
